<script setup>
  import { onMounted, reactive, ref, computed, watch, nextTick, onBeforeMount } from 'vue';
  import { transformGCJ2WGS } from "@/function/lib/transformGCJ2WGS.js";
  import { transformWGS2GCJ } from "@/function/lib/transformWGS2GCJ.js";
  import { ElMessage } from "element-plus";

  defineOptions({name: ''});
  const props = defineProps({})
  const emits = defineEmits(['on-ok', 'on-calc-area']);
  const TMap = ref(null);
  const keyword = ref('');
  const mapKeyId = ref('container' + new Date().getTime());
  const mapHeight = ref(null);
  const mode = ref('onlyView');  // 模式 open：无限制，onlyView：仅查看，无法放大缩小等其他操作
  // const latlngList = ref(["30.062831079085765,120.56957754864416;30.055369926433098,120.57034548223307;30.059621498750122,120.58906917691188"]);
  const latlngList = ref(['30.052962,120.58734;30.04262,120.590616;30.043248,120.576144;30.054496,120.580601;', '30.053620626713194,120.57786243484225;30.04801616359802,120.57310982016719;30.047744586684246,120.58433323435669']); // 围栏坐标点集
  const editeFenceIndex = ref(-1); // 当前操作的围栏下标
  const editFenceFlag = ref(false); // 是否开启编辑
  const delMarkerIndex = ref(-1); // 当前删除的点下标
  const addMarkerPos = ref({}); // 当前要手动添加的morKer的坐标位置
  const primaryColor = ref('#0249f9');
  const fenceAssemblyList = ref([]);
  
  function init() {
    editeFenceIndex.value = -1;
    editFenceFlag.value = false;
    delMarkerIndex.value = -1;
    addMarkerPos.value = {};
    fenceAssemblyList.value = [];
    try {
      const list = Array.isArray(latlngList.value) ? latlngList.value : JSON.parse(latlngList.value);
      fenceAssemblyList.value = list.map(processItem);
      if (fenceAssemblyList.value.length === 0) {
        initFenceAssemblyList();
      }
    } catch (error) {
      initFenceAssemblyList();
    }
    // primaryColor.value = getComputedStyle(document.documentElement).getPropertyValue('--primary-color');
    if (mode.value === 'open' && fenceAssemblyList.value.length > 0 && editeFenceIndex.value === -1) {
      editFenceFn(0);
    }
    initTMap();
  }
  // 映射电子围栏数据
  function processItem(item) {
    const arr = item.split(';').filter(Boolean);
    const latlngArr = arr.map(ele => {
      const [lat, lng] = ele.split(',');
      const data = transformGCJ2WGS(Number(lat), Number(lng));
      return `${data.lat},${data.lon}`
    });
    return {
      TMapMarker: [],
      polygon: null,
      latlngArr: latlngArr,
      latlngStr: latlngArr.join(';'),
    };
  }
  // 初始电子围栏
  function initFenceAssemblyList() {
    fenceAssemblyList.value = [{
      TMapMarker: [],
      latlngArr: [],
      latlngStr: '',
      polygon: null,
    }];
    editFenceFn(0);
  }
  function calcPolygonAreaFn() {
    let handler = new T.PolygonTool(TMap.value);      //创建标注工具对象
    let area = 0;
    fenceAssemblyList.value.forEach(item => {
      if (item.points) {
        area += handler.getArea(item.points)
      }
    })
    return area;
  }
  function calculateCenter(points) {
    let sumLng = 0;
    let sumLat = 0;
    const arr = points.map(point => {
      const [lat, lng] = point.split(',')
      sumLng += Number(lng);
      sumLat += Number(lat);
      return {lat, lng}
    })
    const averageLongitude = sumLng / arr.length;
    const averageLatitude = sumLat / arr.length;
    return {
      center_lat: averageLatitude,
      center_lng: averageLongitude,
    };
  }
  async function initTMap() {
    if (TMap.value) {
      destructionTMap(); // 销毁已存在的地图实例
    }
    await nextTick(() => {
      // 转换坐标（中心点）
      const {center_lat, center_lng} = editeFenceIndex.value !== -1 ? calculateCenter(fenceAssemblyList.value[editeFenceIndex.value].latlngArr) : {center_lat: 30.051814, center_lng: 120.583359};
      const data = transformGCJ2WGS(Number(center_lat) || 30.051814, Number(center_lng) || 120.583359);
      const center = new T.LngLat(data.lon, data.lat);
      // 初始化地图
      TMap.value = new T.Map(mapKeyId.value);
      TMap.value.centerAndZoom(center, 15);
      if (mode.value === 'onlyView') {
        setupViewOnlyMode();
      } else {
        setupEditMode();
      }
      operateTMap();
    });
  }
  // 视图模式专用设置
  function setupViewOnlyMode() {
    const infoWindow = new T.InfoWindow(`<font color='#000000'>位置：${keyword.value || '暂无'}</font>`);
    TMap.value.openInfoWindow(infoWindow, TMap.value.getCenter());
  }
  // 编辑模式专用设置
  function setupEditMode() {
    // 定义一个辅助函数来检查并处理添加标记点的逻辑
    const checkAndAddMarker = (event, liJiZX = false) => {
      console.log('editeFenceIndex.value', editeFenceIndex.value);
      
      if (!editFenceFlag.value) return;
      if (fenceAssemblyList.value[editeFenceIndex.value].latlngArr?.length >= 20) {
        ElMessage({
          message: '电子围栏最多允许添加20个坐标点！',
          type: 'warning',
        })
        return;
      }
      addMarkerPos.value = event.lnglat;
      if (liJiZX) {
        addMarker(true);
        contextmenuFn(''); // 隐藏右键菜单
      } else {
        contextmenuFn('map', event.containerPoint.x, event.containerPoint.y); // 打开右键菜单
      }
    };
    // 监听地图点击事件
    TMap.value.addEventListener('click', (event) => {
      checkAndAddMarker(event, true);
    });
    // 监听地图右键菜单事件
    TMap.value.addEventListener('contextmenu', (event) => {
      checkAndAddMarker(event);
    });
  }
  // 手动删除点
  function delMarkerFn() {
    // 删除指定下标的点
    fenceAssemblyList.value[editeFenceIndex.value].latlngArr.splice(delMarkerIndex.value, 1);
    fenceAssemblyList.value[editeFenceIndex.value].latlngStr = fenceAssemblyList.value[editeFenceIndex.value].latlngArr.join(';');
    // 右键菜单隐藏
    contextmenuFn('');
    // 重新渲染天地图
    operateTMap();
  }
  function editFenceFn(index) {
    // 检查当前是否有正在编辑的围栏且点数不足三个
    if (editFenceFlag.value && editeFenceIndex.value !== -1 && (fenceAssemblyList.value[editeFenceIndex.value].latlngArr || []).length < 3) {
      ElMessage({
        message: '至少需要三个点才能编辑电子围栏！',
        type: 'warning',
      })
      return;
    }
    // 切换编辑状态
    editFenceFlag.value = !editFenceFlag.value;
    // 如果关闭编辑状态，则重置索引
    editeFenceIndex.value = editFenceFlag.value ? index : -1;
    // 隐藏右键菜单
    contextmenuFn('');
    operateTMap();
  }
  // 渲染天地图
  function operateTMap() {
    if (!TMap.value) return;
    // 先清除所有覆盖物
    TMap.value.clearOverLays();
    fenceAssemblyList.value.forEach((item, index) => {
      const data = item.latlngArr || [];
      // 需要编辑的多边形，将顶点渲染为图像标注在地图上
      if (editFenceFlag.value && editeFenceIndex.value === index) {
        // 先移除监听
        if ((item.TMapMarker || []).length > 0) {
          item.TMapMarker.forEach(ele => {
            ele.removeEventListener('dragend');
            ele.removeEventListener('contextmenu');
          })
        }
        item.TMapMarker = [];
        data.forEach(ele => {
          const [lat, lng] = ele.split(',');
          addMarkerPos.value = new T.LngLat(lng, lat)
          addMarker();
        })
      }
      // 创建并添加多边形对象
      const points = data.map(ele => {
        const [lat, lng] = ele.split(',');
        return new T.LngLat(lng, lat);
      });
      if (points.length >= 3) { // 确保有足够的点来创建一个多边形
        item.points = points
        item.polygon = new T.Polygon(points, {
          color: primaryColor.value,
          weight: 3,
          opacity: 1,
          fillColor: "#44aaf8",
          fillOpacity: 0.3
        });
        TMap.value.addOverLay(item.polygon);
        // item.polygon.enableEdit();
        emits('on-calc-area', calcPolygonAreaFn())
      }
    })
  }
  function addMarker(isManualAdd = false) {
    const latLng = addMarkerPos.value;
    if (!TMap.value || !latLng) return;
    const editMapData = fenceAssemblyList.value[editeFenceIndex.value];
    if (!editMapData) return;
    // 获取当前标记的数量（下标）
    const markerIndex = editMapData.TMapMarker ? editMapData.TMapMarker.length : 0;
    // 生成文本图像（假设这是一个异步操作）
    generateTextImage(markerIndex + 1, (url) => {
      const icon = new T.Icon({
        iconUrl: url,
        iconAnchor: new T.Point(10, 10)
      });
      // 创建标记
      const marker = new T.Marker(latLng, {icon: icon});
      editMapData.TMapMarker.push(marker); // 直接推入数组，使用数组长度作为索引
      // 将标记添加到地图上
      TMap.value.addOverLay(marker);
      // 开启拖拽
      marker.enableDragging();
      // 监听拖拽完成事件
      marker.addEventListener('dragend', (event) => {
        const {lat, lng} = event.lnglat;
        const latlngStr = `${lat},${lng}`;
        editMapData.latlngArr[markerIndex] = latlngStr; // 使用正确的索引更新数据
        editMapData.latlngStr = editMapData.latlngArr.join(';');
        operateTMap(); // 重新渲染地图以反映更改
      });
      // 监听右键菜单事件
      marker.addEventListener('contextmenu', (event) => {
        delMarkerIndex.value = markerIndex;
        contextmenuFn('marKer', event.containerPoint.x, event.containerPoint.y);
      })
      // 如果是手动添加，则立即更新围栏数据并调用 operateTMap
      if (isManualAdd) {
        const {lat, lng} = latLng;
        const latlngStr = `${lat},${lng}`;
        editMapData.latlngArr.push(latlngStr); // 如果是手动添加，可能需要推入新元素
        editMapData.latlngStr = editMapData.latlngArr.join(';');
        contextmenuFn('');
        operateTMap();
      }
    });
  }
  // 生成带序号的图片
  function generateTextImage(text, callback) {
    // 创建Canvas元素
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    // 设置Canvas大小
    canvas.width = 20;
    canvas.height = 20;
    ctx.beginPath();
    ctx.arc(10, 10, 10, 0, 2 * Math.PI);
    // 绘制背景
    ctx.fillStyle = primaryColor.value;
    ctx.fill();
    // 绘制文字
    ctx.fillStyle = '#ffffff';
    ctx.font = '15px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(text || 1, canvas.width / 2, canvas.height / 1.8);
    // 将Canvas转换为DataURL格式的图片
    var dataURL = canvas.toDataURL('image/png');
    callback(dataURL)
  }
  // 销毁天地图
  function destructionTMap() {
    if (TMap.value) {
      // 直接将节点给删掉
      const parentEl = document.getElementById('mainMap');
      const cahildrenEl = document.getElementById(mapKeyId.value);
      if (parentEl && cahildrenEl) parentEl.removeChild(cahildrenEl);
      // 然后再手动将节点加进来
      const newCahildrenEl = document.createElement("div");
      newCahildrenEl.id = mapKeyId.value;
      newCahildrenEl.style = `height: ${mapHeight.value ? (mapHeight.value + 'px') : '70vh'};width: 100%;`;
      parentEl.appendChild(newCahildrenEl);
      TMap.value = null;
    }
  }
  // // 添加电子围栏
  // function addFence() {
  //   fenceAssemblyList.value.push({
  //     TMapMarker: [],
  //     latlngArr: [],
  //     latlngStr: '',
  //     polygon: [],
  //   });
  //   // 自动开启编辑
  //   editFenceFn(fenceAssemblyList.value.length - 1);
  // }
  // // 删除电子围栏
  // function delFence(index) {
  //   fenceAssemblyList.value.splice(index, 1);
  //   if (editeFenceIndex.value === index) {
  //     editeFenceIndex.value = -1;
  //     editFenceFlag.value = false;
  //   }
  //   operateTMap();
  // }
  // 右键菜单操作
  function contextmenuFn(mode = '', left = null, top = null) {
    if (mode && left && top) {
      // 打开指定菜单
      const contextmenu = document.getElementById('contextmenu_' + mode);
      contextmenu.style.display = 'block';
      contextmenu.style.left = left + 'px';
      contextmenu.style.top = top + 'px';
    }
    // 隐层其他右键菜单
    ['map', 'polygon', 'marKer'].filter(item => item !== mode).forEach(item => {
      const contextmenu = document.getElementById('contextmenu_' + item);
      contextmenu.style.display = 'none';
    });
  }
  function submit(callBack = null) {
    if (editeFenceIndex.value !== -1 && (fenceAssemblyList.value[editeFenceIndex.value].latlngArr || []).length < 3 && editFenceFlag.value) {
      callBack([])
      // emits('on-ok', []);
      return;
    }
    const data = fenceAssemblyList.value.map(item => {
      return item.latlngArr.map(ele => {
        const [lat, lng] = ele.split(',')
        const data = transformWGS2GCJ(Number(lat), Number(lng))
        return data.lat + ',' + data.lon;
      }).join(';')
    })
    // emits('on-ok', data);
    callBack(data)
  }
  // 测试保存
  function save() {
    submit(data => {
      console.log(data);
    })
  }

  onMounted(() => {
    setTimeout(() => {
      init();
    }, 1000);
  });

  onBeforeMount(() => {
    if (TMap.value) destructionTMap();
  });

  // 子组件暴露
  defineExpose({});

</script>

<template>
  <div id="mainMap">
    <div class="tips">
      <el-tooltip
        class="box-item"
        effect="dark"
        content="Left Top prompts info"
        placement="left-start"
      >
        <el-icon size="30"><WarningFilled /></el-icon>
        <template #content>
          <p>1、通过鼠标右键点击选择菜单，或直接在地图区域上单击，即可添加坐标点。此外，您还可以自由拖动这些顶点，以调整并精确塑造您所需的区域形状。</p>
          <p>2、注意：最多可添加20个顶点</p>
        </template>
      </el-tooltip>
    </div>
    <div class="save" @click="save">保存</div>
    <div :id="mapKeyId" style="height: 100%;width: 100%;"></div>
    <!-- 地图右键菜单 -->
    <div id="contextmenu_map" class="contextmenu_map">
      <div class="contextmenu_map_item" @click="addMarker(true)">添加坐标点</div>
    </div>
    <!-- 多边形右键菜单 -->
    <div id="contextmenu_polygon" class="contextmenu_polygon">
      <!-- <div class="contextmenu_polygon_item" @click="editFenceFn">完成编辑</div>
      <div class="contextmenu_polygon_item" @click="delFence">删除电子围栏</div>   -->
    </div>
    <!-- marKer右键菜单 -->
    <div id="contextmenu_marKer" class="contextmenu_marKer">
      <div class="contextmenu_marKer_item" @click="delMarkerFn">删除</div>
    </div>
  </div>
</template>

<style lang="less" scoped>
#mainMap {
  width: 100%;
  height: 100%;
  background-color: #f1f1f1;
  color: #000;
  position: relative;

  .tips {
    position: absolute;
    right: 10px;
    z-index: 2000;
    top: 10px;
  }
  .save {
    position: absolute;
    left: 10px;
    z-index: 2000;
    top: 10px;
  }

  .fenceItem {
    // position: relative;
    margin-bottom: 10px;

    .h1Title {
      border-bottom: none;
      padding-bottom: 0;
      margin-bottom: 0;
    }

    .butBox {
      display: flex;
    }
  }

  .mainRight {
    position: relative;

    .but {
      position: absolute;
      top: 10px;
      left: 10px;
      z-index: 400;
    }
  }

  .contextmenu_map,
  .contextmenu_polygon,
  .contextmenu_marKer {
    display: none;
    position: absolute;
    z-index: 1000;
    background-color: #f9f9f9;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 5px 0;
    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);

    &_item {
      padding: 10px 20px;
      cursor: pointer;
    }

    &_item:hover {
      background-color: #f1f1f1;
    }
  }
}
</style>
